home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / binutils.252 / gas / input-fi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-27  |  5.3 KB  |  241 lines

  1. /* input_file.c - Deal with Input Files -
  2.    Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GAS, the GNU Assembler.
  5.  
  6.    GAS is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    GAS is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GAS; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /*
  21.  * Confines all details of reading source bytes to this module.
  22.  * All O/S specific crocks should live here.
  23.  * What we lose in "efficiency" we gain in modularity.
  24.  * Note we don't need to #include the "as.h" file. No common coupling!
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29.  
  30. #include "as.h"
  31. #include "input-file.h"
  32.  
  33. /* This variable is non-zero if the file currently being read should be
  34.    preprocessed by app.  It is zero if the file can be read straight in.
  35.    */
  36. int preprocess = 0;
  37.  
  38. /*
  39.  * This code opens a file, then delivers BUFFER_SIZE character
  40.  * chunks of the file on demand.
  41.  * BUFFER_SIZE is supposed to be a number chosen for speed.
  42.  * The caller only asks once what BUFFER_SIZE is, and asks before
  43.  * the nature of the input files (if any) is known.
  44.  */
  45.  
  46. #define BUFFER_SIZE (32 * 1024)
  47.  
  48. /*
  49.  * We use static data: the data area is not sharable.
  50.  */
  51.  
  52. static FILE *f_in;
  53. static char *file_name;
  54.  
  55. /* Struct for saving the state of this module for file includes.  */
  56. struct saved_file
  57.   {
  58.     FILE *f_in;
  59.     char *file_name;
  60.     int preprocess;
  61.     char *app_save;
  62.   };
  63.  
  64. /* These hooks accomodate most operating systems. */
  65.  
  66. void 
  67. input_file_begin ()
  68. {
  69.   f_in = (FILE *) 0;
  70. }
  71.  
  72. void 
  73. input_file_end ()
  74. {
  75. }
  76.  
  77. /* Return BUFFER_SIZE. */
  78. unsigned int 
  79. input_file_buffer_size ()
  80. {
  81.   return (BUFFER_SIZE);
  82. }
  83.  
  84. int 
  85. input_file_is_open ()
  86. {
  87.   return f_in != (FILE *) 0;
  88. }
  89.  
  90. /* Push the state of our input, returning a pointer to saved info that
  91.    can be restored with input_file_pop ().  */
  92. char *
  93. input_file_push ()
  94. {
  95.   register struct saved_file *saved;
  96.  
  97.   saved = (struct saved_file *) xmalloc (sizeof *saved);
  98.  
  99.   saved->f_in = f_in;
  100.   saved->file_name = file_name;
  101.   saved->preprocess = preprocess;
  102.   if (preprocess)
  103.     saved->app_save = app_push ();
  104.  
  105.   input_file_begin ();        /* Initialize for new file */
  106.  
  107.   return (char *) saved;
  108. }
  109.  
  110. void
  111. input_file_pop (arg)
  112.      char *arg;
  113. {
  114.   register struct saved_file *saved = (struct saved_file *) arg;
  115.  
  116.   input_file_end ();        /* Close out old file */
  117.  
  118.   f_in = saved->f_in;
  119.   file_name = saved->file_name;
  120.   preprocess = saved->preprocess;
  121.   if (preprocess)
  122.     app_pop (saved->app_save);
  123.  
  124.   free (arg);
  125. }
  126.  
  127. void
  128. input_file_open (filename, pre)
  129.      char *filename;        /* "" means use stdin. Must not be 0. */
  130.      int pre;
  131. {
  132.   int c;
  133.   char buf[80];
  134.  
  135.   preprocess = pre;
  136.  
  137.   assert (filename != 0);    /* Filename may not be NULL. */
  138.   if (filename[0])
  139.     {                /* We have a file name. Suck it and see. */
  140.       f_in = fopen (filename, "r");
  141.       file_name = filename;
  142.     }
  143.   else
  144.     {                /* use stdin for the input file. */
  145.       f_in = stdin;
  146.       file_name = "{standard input}";    /* For error messages. */
  147.     }
  148.   if (f_in == (FILE *) 0)
  149.     {
  150.       as_perror ("Can't open %s for reading", file_name);
  151.       return;
  152.     }
  153.  
  154.   c = getc (f_in);
  155.   if (c == '#')
  156.     {                /* Begins with comment, may not want to preprocess */
  157.       c = getc (f_in);
  158.       if (c == 'N')
  159.     {
  160.       fgets (buf, 80, f_in);
  161.       if (!strcmp (buf, "O_APP\n"))
  162.         preprocess = 0;
  163.       if (!strchr (buf, '\n'))
  164.         ungetc ('#', f_in);    /* It was longer */
  165.       else
  166.         ungetc ('\n', f_in);
  167.     }
  168.       else if (c == '\n')
  169.     ungetc ('\n', f_in);
  170.       else
  171.     ungetc ('#', f_in);
  172.     }
  173.   else
  174.     ungetc (c, f_in);
  175. }
  176.  
  177. /* Close input file.  */
  178. void 
  179. input_file_close ()
  180. {
  181.   if (f_in != NULL)
  182.     {
  183.       fclose (f_in);
  184.     }                /* don't close a null file pointer */
  185.   f_in = 0;
  186. }                /* input_file_close() */
  187.  
  188. char *
  189. input_file_give_next_buffer (where)
  190.      char *where;        /* Where to place 1st character of new buffer. */
  191. {
  192.   char *return_value;        /* -> Last char of what we read, + 1. */
  193.   register int size;
  194.  
  195.   if (f_in == (FILE *) 0)
  196.     return 0;
  197.   /*
  198.    * fflush (stdin); could be done here if you want to synchronise
  199.    * stdin and stdout, for the case where our input file is stdin.
  200.    * Since the assembler shouldn't do any output to stdout, we
  201.    * don't bother to synch output and input.
  202.    */
  203.   if (preprocess)
  204.     {
  205.       char *p;
  206.       int n;
  207.       int ch;
  208.       extern FILE *scrub_file;
  209.  
  210.       scrub_file = f_in;
  211.       for (p = where, n = BUFFER_SIZE; n; --n)
  212.     {
  213.  
  214.       ch = do_scrub_next_char (scrub_from_file, scrub_to_file);
  215.       if (ch == EOF)
  216.         break;
  217.       *p++ = ch;
  218.     }
  219.       size = BUFFER_SIZE - n;
  220.     }
  221.   else
  222.     size = fread (where, sizeof (char), BUFFER_SIZE, f_in);
  223.   if (size < 0)
  224.     {
  225.       as_perror ("Can't read from %s", file_name);
  226.       size = 0;
  227.     }
  228.   if (size)
  229.     return_value = where + size;
  230.   else
  231.     {
  232.       if (fclose (f_in))
  233.     as_perror ("Can't close %s", file_name);
  234.       f_in = (FILE *) 0;
  235.       return_value = 0;
  236.     }
  237.   return (return_value);
  238. }
  239.  
  240. /* end of input-file.c */
  241.